﻿using LdtDataEngin.ModuleDetail.BaseModule.UIEExtract;
using LdtJudge.DataEngine.Common;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Xml;

namespace LdtDataEngin.ModuleDetail.BaseModule
{
    /// <summary>
    /// UIE模型数据处理类
    /// </summary>
    public class UieModelHandleClass
    {
        /// <summary>
        /// UIE模型数据转XML
        /// </summary>
        public XmlDocument UieModelToXml(List<UIEModelNode> uieModels,string rootName)
        {
            XmlDocument xmlDoc = new XmlDocument();
            XmlNode root = xmlDoc.CreateElement(rootName);
            xmlDoc.AppendChild(root);
            if (uieModels != null && uieModels.Any())
            {
                foreach (var nodeModel in uieModels)
                {
                    InitNode(xmlDoc, nodeModel,"");
                }
            }
            return xmlDoc;
        }

        /// <summary>
        /// 加载子级节点数据
        /// </summary>
        /// <param name="parentNode">父级节点</param>
        /// <param name="modelInfo">uieModel数据</param>
        /// <param name="prePath">节点下标和节点id属性值</param>
        private void InitNode(XmlDocument doc, UIEModelNode modelInfo,string prePath)
        {
            XmlNode currentNode = null;
            List<string> modelNodeNames = new List<string>();
            if (!string.IsNullOrWhiteSpace(modelInfo.Span) && !string.IsNullOrWhiteSpace(modelInfo.Code) && modelInfo.Code.Contains("@"))
            {
                string nodeAllPath = modelInfo.Code.Trim('/');
                int attrIndex = nodeAllPath.LastIndexOf("@");
                string modelNodePath = nodeAllPath.Substring(0, attrIndex - 1);
                string queryPath = modelNodePath;
                modelNodeNames = modelNodePath.Split("/", StringSplitOptions.RemoveEmptyEntries).ToList();
                if(!string.IsNullOrWhiteSpace(prePath))
                {
                    if(prePath.EndsWith("]"))
                    {
                        int conditionIndex= prePath.LastIndexOf("[");
                        string replacePath = prePath.Substring(0, conditionIndex);
                        queryPath = queryPath.Replace(replacePath, prePath);
                    }
                }

                string attrName = nodeAllPath.Split("@", StringSplitOptions.RemoveEmptyEntries).LastOrDefault();
                var nodes = doc.SelectNodes(queryPath);
                bool isCreate = false;
                if(nodes==null || nodes.Count<1)
                {
                    isCreate = true;
                }
                else
                {
                    if(nodes.Count>0)
                    {
                        foreach (XmlNode nodeItem in nodes)
                        {
                            var attrInfo = nodeItem.Attributes[attrName];
                            if (attrInfo != null)
                            {
                                isCreate = true;
                                break;
                            }
                        }
                        if(!isCreate)
                            currentNode = doc.SelectSingleNode(queryPath);
                    }
                }                  
                
                if (isCreate)
                    currentNode = CreateNode(doc, queryPath);
                if (!string.IsNullOrWhiteSpace(attrName))
                {
                    XmlAttribute attr = currentNode.Attributes[attrName];
                    if (attr == null)
                    {
                        attr = doc.CreateAttribute(attrName);
                        attr.Value = modelInfo.Span;
                        currentNode.Attributes.Append(attr);
                    }
                    else
                    {
                        attr.Value = modelInfo.Span;
                    }
                }
            }

            if (modelInfo.Relations != null && modelInfo.Relations.Any())
            {
                string modelQueryPath = string.Empty;
                if (currentNode != null)
                {
                    XmlAttribute idAttr= doc.CreateAttribute("id");
                    idAttr.Value = Snowflake.Instance().GetId().ToString();
                    currentNode.Attributes.Append(idAttr);
                    string modelPath = string.Join("/", modelNodeNames);
                    modelQueryPath = $"{modelPath}[@id='{idAttr.Value}']";
                }
                foreach (var subItem in modelInfo.Relations)
                {
                    InitNode(doc, subItem,modelQueryPath);
                }
            }
        }

        /// <summary>
        /// 通过xpath路径生成节点
        /// </summary>
        private XmlNode CreateNode(XmlDocument doc, string path)
        {
            XmlNode node = null;
            if (!string.IsNullOrWhiteSpace(path))
            {
                var nodeNames = path.Split("/", StringSplitOptions.RemoveEmptyEntries);
                var parentPath = string.Join('/', nodeNames.Take(nodeNames.Length-1));
                XmlNode parentNode = doc.SelectSingleNode(parentPath);
                if (parentNode == null)
                    parentNode = CreateNode(doc, parentPath);
                string currentNodeName = nodeNames.LastOrDefault();
                if(currentNodeName.Contains("["))
                {
                    currentNodeName = currentNodeName.Split('[')[0];
                }
                node = doc.CreateElement(currentNodeName);
                parentNode.AppendChild(node);
            }
            return node;
        }
    }
}
